﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace SkinableFormsLib
{
    public class Utils
    {
        public static void BitmapMakeTransparent(ref Bitmap bitmap, ref Rectangle bounds, ref byte bc, ref byte gc, ref byte rc)
        {
            BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
            {
                if (Marshal.ReadByte(bd.Scan0, i + 3) > 0 && Marshal.ReadByte(bd.Scan0, i) == bc && Marshal.ReadByte(bd.Scan0, i + 1) == gc && Marshal.ReadByte(bd.Scan0, i + 2) == rc)
                    Marshal.WriteByte(bd.Scan0, i + 3, 0);

            }

            bitmap.UnlockBits(bd);

        }



        public static void BitmapMakeTransparentUnsafe(ref Bitmap bitmap, ref Rectangle bounds, ref byte bc, ref byte gc, ref byte rc)
        {
            BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            unsafe
            {
                for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
                {
                    byte* row = (byte*)bd.Scan0 + i;
                    //if alpha not zero and channels match backcolor set alpha to 0
                    //bitblt and such failed
                    if (row[3] > 0 && row[0] == bc && row[1] == gc && row[2] == rc)
                        row[3] = 0;

                }
            }
            bitmap.UnlockBits(bd);

        }


        public static int MAKELONG(int low, int high)
        {
            return (high << 16) | (low & 0xffff);
        }

        public static IntPtr MAKELPARAM(int low, int high)
        {
            return (IntPtr)((high << 16) | (low & 0xffff));
        }

        public static int HIWORD(int n)
        {
            return (n >> 16) & 0xffff;
        }

        public static int HIWORD(IntPtr n)
        {
            return HIWORD(unchecked((int)(long)n));
        }

        public static int LOWORD(int n)
        {
            return n & 0xffff;
        }

        public static int LOWORD(IntPtr n)
        {
            return LOWORD(unchecked((int)(long)n));
        }

        public static int SignedHIWORD(IntPtr n)
        {
            return SignedHIWORD(unchecked((int)(long)n));
        }
        public static int SignedLOWORD(IntPtr n)
        {
            return SignedLOWORD(unchecked((int)(long)n));
        }

        public static int SignedHIWORD(int n)
        {
            int i = (int)(short)((n >> 16) & 0xffff);

            return i;
        }

        public static int SignedLOWORD(int n)
        {
            int i = (int)(short)(n & 0xFFFF);

            return i;
        } 

    }
}
